/** ****************************************************************************
 * CopyRight (C) 2012 Sharadendu Sinha.
 * Licensing : FreeBSD 
 *
 * @(#) $Id$
 */
package com.sps.signalling;

import com.sps.signalling.InvokableConnection.Type;
import com.sps.signalling.exceptions.SignallingException;

/**
 * This class is the base interface for all classes that are capable of emiting
 * {@link Signal}s. it extends from {@link InvokableProvider}. This interface
 * has three main methods <li>connect - This is used to connect a {@link Signal}
 * to an {@link Invokable}</li> <li>disconnect - This is used to disconnect a
 * {@link Signal} to an {@link Invokable}</li> <li>emit - This method is used to
 * emit a {@link Signal}</li>
 * 
 * @version 1.1
 * @author sharadendu
 */
public interface SignalEmmiter
	extends InvokableProvider
{
	/**
	 * Connect signal with invokable using the connectionType on this
	 * {@link SignalEmmiter}
	 * 
	 * @param signal {@link Invokable}
	 * @param invokable {@link Invokable}
	 * @param connectionType {@link Type}
	 ****************************************************************************/
	void connect(Invokable signal, Invokable invokable, Type connectionType);

	/**
	 * Connect signal with invokable using the connectionType on signalEmmiter
	 * 
	 * @param signalEmmiter {@link SignalEmmiter}
	 * @param signalName name of the {@link Signal}
	 * @param invokable {@link Invokable}
	 * @param connectionType {@link Type}
	 * @throws SignallingException if no {@link Signal} is found with the given
	 *             name
	 ****************************************************************************/
	void connect(SignalEmmiter signalEmmiter, String signalName,
		Invokable invokable, Type connectionType) throws SignallingException;

	/**
	 * Connect signal with invokable on this {@link SignalEmmiter}
	 * 
	 * @param signal
	 * @param invokable
	 ****************************************************************************/
	void connect(Invokable signal, Invokable invokable);

	/**
	 * Connect signal with invokable using the {@link Type#DIRECT} on
	 * signalEmmiter
	 * 
	 * @param signalEmmiter {@link SignalEmmiter}
	 * @param signalName signalName name of the {@link Signal}
	 * @param invokable {@link Invokable}
	 * @throws SignallingException if no {@link Signal} is found with the given
	 *             name
	 ****************************************************************************/
	void connect(SignalEmmiter signalEmmiter, String signalName,
		Invokable invokable) throws SignallingException;

	/**
	 * Connect {@link Signal} identified by signalName with invokable using the
	 * {@link Type#DIRECT} on this {@link SignalEmmiter}
	 * 
	 * @param signalName name of the {@link Signal}
	 * @param invokable {@link Invokable}
	 * @throws SignallingException
	 ****************************************************************************/
	void connect(String signalName, Invokable invokable)
		throws SignallingException;

	/**
	 * Connect {@link Signal} identified by signalName with invokable using the
	 * type on this {@link SignalEmmiter}
	 * 
	 * @param signalName name of the {@link Signal}
	 * @param invokable {@link Invokable}
	 * @param type {@link Type}
	 * @throws SignallingException
	 ****************************************************************************/
	void connect(String signalName, Invokable invokable, Type type)
		throws SignallingException;

	/**
	 * Disconnect signal with invokable with the connection type as type
	 * 
	 * @param signal {@link Signal}
	 * @param invokable {@link Invokable}
	 * @param type {@link Type}
	 * @throws SignallingException if no {@link InvokableConnection} is found
	 ****************************************************************************/
	void discconnect(Invokable signal, Invokable invokable, Type type)
		throws SignallingException;

	/**
	 * Disconnect signal with invokable with the connection type as
	 * {@link Type#DIRECT}
	 * 
	 * @param signal {@link Signal}
	 * @param invokable {@link Invokable}
	 * @throws SignallingException if no {@link InvokableConnection} is found
	 ****************************************************************************/
	void discconnect(Invokable signal, Invokable invokable)
		throws SignallingException;

	/**
	 * Disconnect signal identified by signalName with invokable with the
	 * connection type as {@link Type#DIRECT} for signalEmmiter
	 * 
	 * @param signalEmmiter {@link SignalEmmiter}
	 * @param signalName name of the {@link Signal}
	 * @param invokable {@link Invokable}
	 * @throws SignallingException SignallingException if no
	 *             {@link InvokableConnection} is found or if {@link Signal} is
	 *             not found with the given name
	 ****************************************************************************/
	void discconnect(SignalEmmiter signalEmmiter, String signalName,
		Invokable invokable) throws SignallingException;

	/**
	 * Disconnect signal identified by signalName with invokable with the
	 * connection type as type for signalEmmiter
	 * 
	 * @param signalEmmiter {@link SignalEmmiter}
	 * @param signalName name of the {@link Signal}
	 * @param invokable {@link Invokable}
	 * @param type {@link Type}
	 * @throws SignallingException if no {@link InvokableConnection} is found or
	 *             if {@link Signal} is not found with the given name
	 ****************************************************************************/
	void discconnect(SignalEmmiter signalEmmiter, String signalName,
		Invokable invokable, Type type) throws SignallingException;

	/**
	 * Disconnect signal identified by signalName with invokable with the
	 * connection type as {@link Type#DIRECT}
	 * 
	 * @param signalName name of the {@link Signal}
	 * @param invokable {@link Invokable}
	 * @throws SignallingException if no {@link InvokableConnection} is found or
	 *             if {@link Signal} is not found with the given name
	 ****************************************************************************/
	void discconnect(String signalName, Invokable invokable)
		throws SignallingException;

	/**
	 * Disconnect signal identified by signalName with invokable with the
	 * connection type as type
	 * 
	 * @param signalName name of the {@link Signal}
	 * @param invokable {@link Invokable}
	 * @param type {@link Type}
	 * @throws SignallingException if no {@link InvokableConnection} is found or
	 *             if {@link Signal} is not found with the given name
	 ****************************************************************************/
	void discconnect(String signalName, Invokable invokable, Type type)
		throws SignallingException;

	/**
	 * Emit a {@link Signal} with the given parameters
	 * 
	 * @param signal {@link Signal} to be emitted
	 * @param paramObjects parameters of this signal emission
	 ****************************************************************************/
	void emit(Signal signal, Object... paramObjects);

	/**
	 * Emit a {@link Signal} identified by signalName with the given parameters.
	 * Ideally use of this method advised as it involves a HashMap lookup every
	 * time a signal is emmitted. Thus users of this class are advised to cache
	 * the instance of {@link Signal} object that they create once and use this
	 * cached reference every time to emit using the other version of emit.
	 * 
	 * @param signalName name of the signal to be emitted
	 * @param paramObjects parameters of this signal emission
	 * @throws SignallingException if Signal is not found
	 */
	void emit(String signalName, Object... paramObjects)
		throws SignallingException;
}
